package com.huawei.hwclouds.vpc.demo;

import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ClientRequestException;
import com.huaweicloud.sdk.core.exception.ServerResponseException;
import com.huaweicloud.sdk.core.http.HttpConfig;
import com.huaweicloud.sdk.vpc.v2.VpcClient;
import com.huaweicloud.sdk.vpc.v2.model.CreateSecurityGroupOption;
import com.huaweicloud.sdk.vpc.v2.model.CreateSecurityGroupRequest;
import com.huaweicloud.sdk.vpc.v2.model.CreateSecurityGroupRequestBody;
import com.huaweicloud.sdk.vpc.v2.model.CreateSecurityGroupResponse;
import com.huaweicloud.sdk.vpc.v2.model.CreateSecurityGroupRuleOption;
import com.huaweicloud.sdk.vpc.v2.model.CreateSecurityGroupRuleRequest;
import com.huaweicloud.sdk.vpc.v2.model.CreateSecurityGroupRuleRequestBody;
import com.huaweicloud.sdk.vpc.v2.model.DeleteSecurityGroupRequest;
import com.huaweicloud.sdk.vpc.v2.model.DeleteSecurityGroupResponse;
import com.huaweicloud.sdk.vpc.v2.model.ListPortsRequest;
import com.huaweicloud.sdk.vpc.v2.model.ListPortsResponse;
import com.huaweicloud.sdk.vpc.v2.model.ListSecurityGroupsRequest;
import com.huaweicloud.sdk.vpc.v2.model.ListSecurityGroupsResponse;
import com.huaweicloud.sdk.vpc.v2.model.UpdatePortOption;
import com.huaweicloud.sdk.vpc.v2.model.UpdatePortRequest;
import com.huaweicloud.sdk.vpc.v2.model.UpdatePortRequestBody;
import com.huaweicloud.sdk.vpc.v2.model.UpdatePortResponse;
import com.huaweicloud.sdk.vpc.v2.region.VpcRegion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;

/**
 * 配置云服务器的访问策略
 */
public class VPCPortBindSecurityGroupDemo {
    private static final Logger logger = LoggerFactory.getLogger(VPCPortBindSecurityGroupDemo.class.getName());

    public static void main(String[] args) {
        // 输入华为云账号的AK、SK
        String ak = "{YOUR AK}";
        String sk = "{YOUR SK}";
        // 云服务器id
        String ecsId = "{ecs_id}";

        ICredential auth = new BasicCredentials()
            .withAk(ak)
            .withSk(sk);

        // HTTP客户端配置
        HttpConfig httpConfig = HttpConfig.getDefaultHttpConfig().withIgnoreSSLVerification(true);

        // v2接口的VpcClient，region_id处填写应用区域的id，如北京四填写cn-north-4
        VpcClient vpcClient = VpcClient.newBuilder()
            .withCredential(auth)
            .withRegion(VpcRegion.valueOf("{region_id}"))
            .withHttpConfig(httpConfig)
            .build();

        VPCPortBindSecurityGroupDemo demo = new VPCPortBindSecurityGroupDemo();
        // 1.通过云服务器的ID查询网卡信息
        ListPortsResponse listPortsResponse = demo.listPorts(vpcClient, ecsId);
        // 2.查询当前已有的安全组信息
        ListSecurityGroupsResponse securityGroupsResponse = demo.listSecurityGroups(vpcClient);
        String portId = listPortsResponse.getPorts().get(0).getId();
        String oldSecurityGroupId = securityGroupsResponse.getSecurityGroups().get(0).getId();
        // 3.创建新安全组和安全组规则
        String newSecurityGroupId = demo.createSecurityGroup(vpcClient);
        // 4.为弹性云服务器添加安全组
        demo.updatePort(vpcClient, portId, Arrays.asList(oldSecurityGroupId, newSecurityGroupId));
        // 5.解除云服务器绑定的安全组
        demo.updatePort(vpcClient, portId, Arrays.asList(oldSecurityGroupId));
        // 6.删除创建的安全组
        demo.deleteSecurityGroup(vpcClient, newSecurityGroupId);
    }

    private ListSecurityGroupsResponse listSecurityGroups(VpcClient vpcClient) {
        ListSecurityGroupsRequest securityGroupsRequest = new ListSecurityGroupsRequest().withLimit(1);
        ListSecurityGroupsResponse securityGroupsResponse = null;
        try {
            securityGroupsResponse = vpcClient.listSecurityGroups(securityGroupsRequest);
            logger.info(securityGroupsResponse.toString());
        } catch (ClientRequestException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.toString());
        } catch (ServerResponseException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.getMessage());
        }
        return securityGroupsResponse;
    }

    private ListPortsResponse listPorts(VpcClient vpcClient, String ecsId) {
        ListPortsRequest listPortsRequest = new ListPortsRequest().withDeviceId(ecsId);
        ListPortsResponse listPortsResponse = null;
        try {
            listPortsResponse = vpcClient.listPorts(listPortsRequest);
            logger.info(listPortsResponse.toString());
        } catch (ClientRequestException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.toString());
        } catch (ServerResponseException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.getMessage());
        }
        return listPortsResponse;
    }

    private void updatePort(VpcClient vpcClient, String portId, List<String> securityGroupList) {
        UpdatePortRequest request = new UpdatePortRequest()
            .withPortId(portId)
            .withBody(new UpdatePortRequestBody()
                .withPort(new UpdatePortOption()
                    .withSecurityGroups(securityGroupList)
                ));
        try {
            UpdatePortResponse updatePortResponse = vpcClient.updatePort(request);
            logger.info(updatePortResponse.toString());
        } catch (ClientRequestException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.toString());
        } catch (ServerResponseException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.getMessage());
        }
    }

    private String createSecurityGroup(VpcClient vpcClient) {
        String securityGroupId = "";
        try {
            // 创建安全组
            CreateSecurityGroupRequest createSecurityGroupRequest = new CreateSecurityGroupRequest()
                .withBody(new CreateSecurityGroupRequestBody()
                    .withSecurityGroup(new CreateSecurityGroupOption()
                        .withName("sg-new-bind")));
            CreateSecurityGroupResponse createSecurityGroupResponse =
                vpcClient.createSecurityGroup(createSecurityGroupRequest);
            logger.info(createSecurityGroupResponse.toString());
            securityGroupId = createSecurityGroupResponse.getSecurityGroup().getId();
            // 创建安全组规则
            CreateSecurityGroupRuleRequest createSecurityGroupRuleRequest =
                new CreateSecurityGroupRuleRequest()
                    .withBody(new CreateSecurityGroupRuleRequestBody()
                        .withSecurityGroupRule(new CreateSecurityGroupRuleOption()
                            .withSecurityGroupId(securityGroupId)
                            .withDirection("ingress")
                            .withEthertype("IPv4")
                            .withProtocol("tcp")
                            .withPortRangeMax(6037)
                            .withPortRangeMin(6037)
                            .withRemoteIpPrefix("192.168.21.0/24")));
            vpcClient.createSecurityGroupRule(createSecurityGroupRuleRequest);
        } catch (ClientRequestException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.toString());
        } catch (ServerResponseException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.getMessage());
        }
        return securityGroupId;
    }

    private void deleteSecurityGroup(VpcClient vpcClient, String securityGroupId) {
        DeleteSecurityGroupRequest deleteSecurityGroupRequest = new DeleteSecurityGroupRequest()
            .withSecurityGroupId(securityGroupId);
        try {
            DeleteSecurityGroupResponse deleteSecurityGroupResponse =
                vpcClient.deleteSecurityGroup(deleteSecurityGroupRequest);
            logger.info(deleteSecurityGroupResponse.toString());
        } catch (ClientRequestException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.toString());
        } catch (ServerResponseException e) {
            logger.error(String.valueOf(e.getHttpStatusCode()));
            logger.error(e.getMessage());
        }
    }
}
